package com.zhou.framework.helper;

import com.zhou.framework.annotation.Inject;
import com.zhou.framework.util.ArrayUtil;
import com.zhou.framework.util.CollectionUtil;
import com.zhou.framework.util.ReflectionUtil;
import org.apache.commons.lang3.ArrayUtils;

import java.lang.reflect.Field;
import java.util.Map;

/**
 * 依赖注入助手类
 *
 * IOC框架中所管理的对象都是单例的，由于IOC框架底层还是从BeanHelper中获取Bean Map的
 * 而Bean Map中的对象都是事先创建好并仿佛这个Bean容器的，所有对象都是单例的
 *
 * @author zhouplus [http://my.oschina.net/u/2303497/blog]
 * @date 2016/4/14  18:11
 * @since 1.0.0
 */

public final class IocHelper {

    static {
        //获取所有Bean类和Bean实例之间的映射关系（简称 Bean Map）
        Map<Class<?>, Object> beanMap = BeanHelper.getBeanMap();
        if (CollectionUtil.isMapEmpty(beanMap)) {
            //遍历 Bean Map
            for (Map.Entry<Class<?>, Object> beanEntry : beanMap.entrySet()) {
                //从BeanMap中获取Bean类和Bean实例
                Class<?> beanClass = beanEntry.getKey();
                Object beanInstance = beanEntry.getValue();
                //获取Bean类定义的所有成员变量 （简称Bean field）
                Field[] beanFields = beanClass.getDeclaredFields();
                if (ArrayUtil.isNotEmpty(beanFields)) {
                    //遍历Bean field
                    for (Field beanField : beanFields) {
                        //判断当前Bean field是否带有 Inject 注解
                        if (beanField.isAnnotationPresent(Inject.class)) {
                            //在Bean Map中获取 Bean Field对应的实例
                            Class<?> beanFieldClass = beanField.getType();
                            Object beanFieldInstance = beanMap.get(beanFieldClass);
                            if (beanFieldInstance != null) {
                                //通过反射初始化Bean Field的值
                                ReflectionUtil.setField(beanInstance, beanField, beanFieldInstance);
                            }
                        }
                    }
                }
            }
        }
    }
}
